package cn.lingyangwl.agile.member.service;

import cn.lingyangwl.agile.member.assembly.AccountDetailAssembly;
import cn.lingyangwl.agile.member.constant.AccountType;
import cn.lingyangwl.agile.member.mapper.AccountDetailMapper;
import cn.lingyangwl.agile.member.model.entity.AccountDetail;
import cn.lingyangwl.agile.member.model.entity.MemberUser;
import cn.lingyangwl.agile.member.model.rqrs.account_detail.AccountDetailPageReq;
import cn.lingyangwl.agile.member.model.rqrs.account_detail.AccountDetailResp;
import cn.lingyangwl.agile.member.model.rqrs.account_detail.AccountDetailSaveReq;
import cn.lingyangwl.framework.data.mate.annotations.FieldBindHandle;
import cn.lingyangwl.framework.mybatis.plus.utils.PageUtil;
import cn.lingyangwl.framework.tool.core.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 账户明细
 *
 * @author shenguangyang
 */
@Slf4j
@Service
public class AccountDetailServiceImpl extends ServiceImpl<AccountDetailMapper, AccountDetail>
    implements IService<AccountDetail>, AccountDetailService {

    @Resource
    private AccountDetailAssembly accountDetailAssembly;
    @Resource
    private MemberUserService userService;
    
    @Override
    @FieldBindHandle
    public IPage<AccountDetailResp> pageAccountDetail(AccountDetailPageReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<AccountDetail> lqw = AccountDetail.lqw()
            .eq(AccountDetail::getAccountType, req.getAccountType())
            .eq(AccountDetail::getMemberId, req.getMemberId())
            .eq(StringUtils.isNotEmpty(req.getFromType()), AccountDetail::getFromType, req.getFromType())
            .ge(Objects.nonNull(beginTime), AccountDetail::getCreatedAt, beginTime)
            .le(Objects.nonNull(endTime), AccountDetail::getCreatedAt, endTime)
            .orderByDesc(AccountDetail::getCreatedAt);
        IPage<AccountDetail> pageData = this.page(PageUtil.to(req), lqw);
        return PageUtil.to(pageData, accountDetailAssembly::toAccountDetailResp);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAccountDetail(AccountDetailSaveReq req){
        BigDecimal accountData = req.getAccountData();
        AccountType accountType = req.getAccountType();
        MemberUser user = req.getUser();
        if (accountType == AccountType.POINT) {
            userService.updatePoint(user, accountData);
        } else if (accountType == AccountType.EXPERIENCE) {
            userService.updateExperience(user, accountData);
        }

        AccountDetail accountPoint = new AccountDetail();
        accountPoint.setAccountType(accountType.getType());
        accountPoint.setFromType(req.getFromType().getFromType());
        accountPoint.setMemberId(req.getUser().getId());
        accountPoint.setRemark(StringUtils.firstNonEmpty(req.getRemark(), req.getFromType().getRemark()));
        accountPoint.setAccountData(accountData);
        this.save(accountPoint);
    }

    @Override
    public void deleteByUserId(Long userId) {
        LambdaQueryWrapper<AccountDetail> lqw = AccountDetail.lqw().eq(AccountDetail::getMemberId, userId);
        this.remove(lqw);
    }
}
